home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
PROGNG_C
/
TURBOCU2.LZH
/
INDEX.ARC
/
INXRTNS.C
< prev
next >
Wrap
Text File
|
1987-08-21
|
11KB
|
305 lines
/*
* INXRTNS.C - index file support routines
*
* Copyright (c) 1987, Jim Mischel
* Modifications:
*
* 08/13/87 - jim - original coding
* 08/21/87 - jim - flush the buffer after every write (iwrite_dat and iwrite_inx)
*/
#include "inxdefs.h"
/************************************************************************/
/* */
/* Internal support routines */
/* */
/************************************************************************/
/*
* iget_next() - read the next index record in sequence.
* If successful, '*irec' contains the next index record and the function
* returns 0.
* If unsuccessful, '*irec' is undefined and the function returns EOF.
*/
int iget_next(df_rec *db_control, inx_rec *irec)
{
/* see if we've already reached the end of the file */
if (irec->if_flags & ETHRD) {
db_control->df_flags |= DF_EOF;
return(EOF);
}
if (irec->if_flags & RTHRD) { /* Right node is a thread pointer */
if (iread_inx(db_control,irec->if_right_node))
return(EOF);
}
else { /* Right node is a tree pointer */
/*
* Read the right node, then follow the left nodes until we come to a leaf.
* We'll know a leaf when the left node pointer is a thread pointer.
*/
if (iread_inx(db_control,irec->if_right_node))
return(EOF);
while (!(db_control->df_inx_buff.if_flags & LTHRD))
if (iread_inx(db_control,db_control->df_inx_buff.if_left_node))
return(EOF);
} /* else */
return(0);
} /* iget_next */
/*
* iget_prev() - read the previous index record in sequence.
* If successful, '*irec' contains the previous index record and the function
* returns 0.
* If unsuccessful, '*irec' is undefined and the function returns EOF.
*/
int iget_prev(df_rec *db_control, inx_rec *irec)
{
if (irec->if_flags & BTHRD) {
db_control->df_flags |= DF_TOF;
return(EOF);
}
if (irec->if_flags & LTHRD) { /* Left node is a thread pointer */
if (iread_inx(db_control,irec->if_left_node))
return(EOF);
}
else { /* Left node is a tree pointer */
/*
* Read the left node, then follow the right nodes until we come to a leaf.
* We'll know a leaf when the right node pointer is a thread pointer.
*/
if (iread_inx(db_control,irec->if_left_node))
return(EOF);
while (!(db_control->df_inx_buff.if_flags & RTHRD))
if (iread_inx(db_control,db_control->df_inx_buff.if_right_node))
return(EOF);
} /* else */
return(0);
} /* iget_prev */
/*
* isearch() - searches for key value '*key' in data file using a simple
* binary tree search.
* The function returns:
* -1 : The specified key was not found. '*db_control->df_inx_buff'
* would be the parent if '*key' was added to the file.
* '*db_control->df_dat_buff' contains the data record last read.
* 0 : The specified key was found. '*db_control->df_inx_buff' contains
* the index record and '*db_control->df_dat_buff' contains the
* data record.
* 1 : The specified key was not found. '*db_control->df_inx_buff'
* would be the parent if '*key' was added to the file.
* '*db_control->df_dat_buff' contains the data record last read.
* 2 : An error was encountered reading either the index or the data file.
* '*db_control->df_inx_buff' and '*db_control->df_dat_buff' are
* undefined.
*/
int isearch(df_rec *db_control, char *key)
{
if (iget_root(db_control))
return(ierrno);
/* Binary tree search */
while (1) {
/* read the data record */
if (iread_dat(db_control,db_control->df_inx_buff.if_dat_ptr))
return(2); /* data file read error */
switch ((*db_control->df_cmp)(key,db_control->df_key_ptr)) {
case -1 : /* key is less than data record key */
if (db_control->df_inx_buff.if_flags & LTHRD)
return(-1); /* thread pointer (not found) */
if (iread_inx(db_control,db_control->df_inx_buff.if_left_node))
return(2); /* index file read error */
break;
case 0 :
return(0); /* found */
case 1 : /* key is greater than data record key */
if (db_control->df_inx_buff.if_flags & RTHRD)
return(1); /* right thread (not found) */
if (iread_inx(db_control,db_control->df_inx_buff.if_right_node))
return(2); /* inx file read error */
break;
default :
puts("invalid return value from comparison routine");
return(2);
} /* switch */
} /* while */
} /* isearch */
/*
* iget_root() - reads the root of the binary tree into the index buffer.
* Returns 0 if successful, error status if unsuccessful. If the file
* is empty, EOF is returned. If unsuccessful, the contents of the index
* buffer is undefined.
*/
int iget_root(df_rec *db_control)
{
if (iread_inx(db_control,0L))
return(ierrno);
if (db_control->df_inx_buff.if_left_node == 0L)
return(ierror(EOF)); /* empty file */
if (iread_inx(db_control,db_control->df_inx_buff.if_left_node))
return(ierrno);
return(0);
} /* iget_root */
/************************************************************************/
/* */
/* File I/O primitives */
/* */
/* These are the only routines that actually access the files. */
/* */
/************************************************************************/
/*
* iread_inx() - reads the index record at seek_pos into the index buffer.
* Returns 0 if successful, I_INXRD if unsuccessful. If unsuccessful,
* the contents of the index buffer is undefined.
*/
int iread_inx(df_rec *db_control, long seek_pos)
{
if (fseek(db_control->df_inx_file,seek_pos,SEEK_SET))
return(ierror(I_INXRD));
db_control->df_inx_ptr = seek_pos;
if (fread(&db_control->df_inx_buff,sizeof(inx_rec),1,
db_control->df_inx_file) != 1)
return(ierror(I_INXRD));
return(ierror(0));
} /* iread_inx */
/*
* iwrite_inx() - write the record from 'irec' to the index file at position
* 'seek_pos'. Returns 0 if successful, I_INXWT if unsuccessful.
*/
int iwrite_inx(df_rec *db_control, inx_rec *irec, long seek_pos)
{
if (fseek(db_control->df_inx_file,seek_pos,SEEK_SET))
return(ierror(I_INXWT));
db_control->df_inx_ptr = seek_pos;
if (fwrite(irec,sizeof(inx_rec),1,db_control->df_inx_file) != 1)
return(ierror(I_INXWT));
if (fflush(db_control->df_inx_file))
return(ierror(I_INXWT));
return(ierror(0));
} /* iwrite_inx */
/*
* iread_dat() - reads the data record at seek_pos into the data buffer.
* Returns 0 if successful, I_DATRD if unsuccessful. If unsuccessful,
* the contents of the data buffer is undefined.
*/
int iread_dat(df_rec *db_control, long seek_pos)
{
if (fseek(db_control->df_dat_file,seek_pos,SEEK_SET))
return(ierror(I_DATRD));
db_control->df_dat_ptr = seek_pos;
if (fread(db_control->df_dat_buff,db_control->df_rec_size,1,
db_control->df_dat_file) != 1)
return(ierror(I_DATRD));
return(ierror(0));
} /* iread_dat */
/*
* iwrite_dat() - write the record from 'datrec' to the data file at position
* 'seek_pos'. Returns 0 if successful, I_DATWT if unsuccessful.
*/
int iwrite_dat(df_rec *db_control, void *datrec, long seek_pos)
{
if (fseek(db_control->df_dat_file,seek_pos,SEEK_SET))
return(ierror(I_DATWT));
db_control->df_dat_ptr = seek_pos;
if (fwrite(datrec,db_control->df_rec_size,1,db_control->df_dat_file) != 1)
return(ierror(I_DATWT));
if (fflush(db_control->df_dat_file))
return(ierror(I_DATWT));
return(ierror(0));
} /* iwrite_dat */
/*
* ierror() - set the global variable 'ierrno' to the value supplied in 'e'
* and return the error number.
*/
int ierror(int e)
{
ierrno = e;
return(ierrno);
}
/************************************************************************/
/* */
/* Comparison routines */
/* */
/* These routines all return -1 if *arg1 < *arg2 */
/* 0 if *arg1 == *arg2 */
/* 1 if *arg1 > *arg2 */
/************************************************************************/
int icmp_uchar(void *arg1, void *arg2)
{
return ((*(unsigned char *)arg1 < *(unsigned char *)arg2) ? -1 :
(*(unsigned char *)arg1 > *(unsigned char *)arg2) ? 1 : 0);
}
int icmp_schar(void *arg1, void *arg2)
{
return ((*(signed char *)arg1 < *(signed char *)arg2) ? -1 :
(*(signed char *)arg1 > *(signed char *)arg2) ? 1 : 0);
}
int icmp_uint(void *arg1, void *arg2)
{
return ((*(unsigned int *)arg1 < *(unsigned int *)arg2) ? -1 :
(*(unsigned int *)arg1 > *(unsigned int *)arg2) ? 1 : 0);
}
int icmp_sint(void *arg1, void *arg2)
{
return ((*(signed int *)arg1 < *(signed int *)arg2) ? -1 :
(*(signed int *)arg1 > *(signed int *)arg2) ? 1 : 0);
}
int icmp_ulong(void *arg1, void *arg2)
{
return ((*(unsigned long *)arg1 < *(unsigned long *)arg2) ? -1 :
(*(unsigned long *)arg1 > *(unsigned long *)arg2) ? 1 : 0);
}
int icmp_slong(void *arg1, void *arg2)
{
return ((*(signed long *)arg1 < *(signed long *)arg2) ? -1 :
(*(signed long *)arg1 > *(signed long *)arg2) ? 1 : 0);
}
int icmp_string(void *arg1, void *arg2)
{
int r;
return(((r = strcmp((char *)arg1, (char *)arg2)) == 0) ? 0 :
(r > 0) ? 1 : -1);
}
#ifdef FLOAT_KEY
int icmp_float(void *arg1, void *arg2)
{
return ((*(float *)arg1 < *(float *)arg2) ? -1 :
(*(float *)arg1 > *(float *)arg2) ? 1 : 0);
}
int icmp_double(void *arg1, void *arg2)
{
return ((*(double *)arg1 < *(double *)arg2) ? -1 :
(*(double *)arg1 > *(double *)arg2) ? 1 : 0);
}
#endif